package com.media.selector.media.model.entity

import android.content.ContentUris
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Parcel
import android.os.Parcelable
import android.provider.MediaStore
import com.media.selector.media.model.loader.BaseCursorLoader

/**
 * date        ：2020/4/29
 * author      ：蒙景博
 * description ：
 */
class MediaEntity : Parcelable {

    val id: Long
    val mimeType: String?
    val contentUri: Uri?
    val size: Long
    val duration: Long

    constructor(id: Long, mimeType: String, size: Long, duration: Long) {
        this.id = id
        this.mimeType = mimeType
        this.contentUri = getUri(id)
        this.size = size
        this.duration = duration
    }

    private constructor(source: Parcel) {
        id = source.readLong()
        mimeType = source.readString()
        contentUri = source.readParcelable(Uri::class.java.classLoader)
        size = source.readLong()
        duration = source.readLong()
    }

    override fun describeContents(): Int = 0

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeLong(id)
        dest.writeString(mimeType)
        dest.writeParcelable(contentUri, 0)
        dest.writeLong(size)
        dest.writeLong(duration)
    }

    fun isCapture(): Boolean = id == ITEM_ID_CAPTURE

    fun isImage(): Boolean = MimeType.isImage(mimeType)

    fun isGif(): Boolean = MimeType.isGif(mimeType)

    fun isVideo(): Boolean = MimeType.isVideo(mimeType)

    private fun getUri(id: Long): Uri? {
        return ContentUris.withAppendedId(when {
            isImage() -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
            isVideo() -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
            else -> BaseCursorLoader.getContentUri()
        }, id)
    }

    override fun equals(other: Any?): Boolean {
        if (other !is MediaEntity) {
            return false
        }
        return (id == other.id && (mimeType != null && mimeType == other.mimeType
                || mimeType == null && other.mimeType == null)
                && (contentUri != null && contentUri == other.contentUri
                || contentUri == null && other.contentUri == null)
                && size == other.size && duration == other.duration)
    }

    override fun hashCode(): Int {
        var result = 1
        result = 31 * result + id.hashCode()
        if (mimeType != null) {
            result = 31 * result + mimeType.hashCode()
        }
        result = 31 * result + contentUri.hashCode()
        result = 31 * result + size.hashCode()
        result = 31 * result + duration.hashCode()
        return result
    }

    companion object {

        const val ITEM_ID_CAPTURE: Long = -1
        const val ITEM_DISPLAY_NAME_CAPTURE = "Capture"

        fun valueOf(cursor: Cursor): MediaEntity {
            val duration = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) MediaStore.MediaColumns.DURATION else "duration"
            return MediaEntity(
                cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)),
                cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE)),
                cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE)),
                cursor.getLong(cursor.getColumnIndex(duration))
            )
        }

        @JvmField
        val CREATOR: Parcelable.Creator<MediaEntity?> = object : Parcelable.Creator<MediaEntity?> {
            override fun createFromParcel(source: Parcel): MediaEntity? = MediaEntity(source)
            override fun newArray(size: Int): Array<MediaEntity?> = arrayOfNulls(size)
        }
    }
}